import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.DropdownMenu
import androidx.compose.material.DropdownMenuItem
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.application
import org.bytedeco.ffmpeg.global.avcodec
import org.bytedeco.ffmpeg.global.avutil
import org.bytedeco.javacv.*
import org.fourthline.cling.UpnpServiceImpl
import org.fourthline.cling.model.meta.LocalDevice
import org.fourthline.cling.model.meta.RemoteDevice
import org.fourthline.cling.model.types.UDAServiceType
import org.fourthline.cling.registry.Registry
import org.fourthline.cling.registry.RegistryListener
import java.awt.Rectangle
import java.awt.Robot
import java.awt.Toolkit
import java.awt.image.BufferedImage
import java.util.concurrent.atomic.AtomicBoolean

/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     URL_ADDRESS *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * MVP版本：
 * 电脑端：用FFmpeg采集屏幕→编码H.264→通过RTSP推流。
 *
 * 电视端：Android APK用VLC库或ExoPlayer拉流播放。
 *
 * 优化方向：
 *
 * 延迟：启用硬件编码+UDP传输（目标<200ms）。
 *
 * 兼容性：适配小米电视的投屏协议（需实测不同型号）。
 *
 * 绕过限制：
 *
 * 若小米限制第三方投屏，可尝试ADB调试模式或root后注入服务。
 */
@Composable
@Preview
fun App() {

    var isRecording by remember { mutableStateOf(false) }
    var recordingThread by remember { mutableStateOf<Thread?>(null) }

    MaterialTheme {
        var expanded by remember { mutableStateOf(false) }
        var selectedDevice by remember { mutableStateOf("选择设备") }
        val devices = listOf("设备1", "设备2", "设备3")

        Column(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.White)
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Box {
                    Button(
                        onClick = { expanded = true },
                        modifier = Modifier.width(200.dp)
                    ) {
                        Text(selectedDevice)
                    }
                    DropdownMenu(
                        expanded = expanded,
                        onDismissRequest = { expanded = false }
                    ) {
                        devices.forEach { device ->
                            DropdownMenuItem(
                                onClick = {
                                    selectedDevice = device
                                    expanded = false
                                }
                            ) {
                                Text(device)
                            }
                        }
                    }
                }

                Button(
                    onClick = {
                        UpnpServiceImpl(object : RegistryListener {
                            override fun remoteDeviceDiscoveryStarted(
                                registry: Registry?,
                                device: RemoteDevice?
                            ) {
                                TODO("Not yet implemented")
                            }

                            override fun remoteDeviceDiscoveryFailed(
                                registry: Registry?,
                                device: RemoteDevice?,
                                ex: java.lang.Exception?
                            ) {
                                TODO("Not yet implemented")
                            }

                            override fun remoteDeviceAdded(
                                registry: Registry?,
                                device: RemoteDevice?
                            ) {
                                TODO("Not yet implemented")
                                println("发现设备：${device?.identity}")
                            }

                            override fun remoteDeviceUpdated(
                                registry: Registry?,
                                device: RemoteDevice?
                            ) {
                                TODO("Not yet implemented")
                            }

                            override fun remoteDeviceRemoved(
                                registry: Registry?,
                                device: RemoteDevice?
                            ) {
                                TODO("Not yet implemented")
                            }

                            override fun localDeviceAdded(
                                registry: Registry?,
                                device: LocalDevice?
                            ) {
                                TODO("Not yet implemented")
                            }

                            override fun localDeviceRemoved(
                                registry: Registry?,
                                device: LocalDevice?
                            ) {
                                TODO("Not yet implemented")
                            }

                            override fun beforeShutdown(registry: Registry?) {
                                TODO("Not yet implemented")
                            }

                            override fun afterShutdown() {
                                TODO("Not yet implemented")
                            }

                        }).controlPoint.search()
                    },
                    colors = ButtonDefaults.buttonColors(
                        backgroundColor = MaterialTheme.colors.primary,
                        contentColor = Color.White
                    )
                ) {
                    Text("搜索")
                }
            }

            Spacer(modifier = Modifier.height(16.dp))

            Box(
                modifier = Modifier.fillMaxSize(),
                contentAlignment = Alignment.Center
            ) {
                Button(
                    onClick = {
                        isRecording = !isRecording
                        if (isRecording) {
                            recordingThread = startScreenCapture("output.mp4")
                        } else {
                            recordingThread?.interrupt()
                        }
                    },
                    colors = ButtonDefaults.buttonColors(
                        backgroundColor = MaterialTheme.colors.primary,
                        contentColor = Color.White
                    ),
                    shape = RoundedCornerShape(8.dp),
                    modifier = Modifier.padding(16.dp)
                ) {
                    Text(if (isRecording) "停止录制" else "开始录制")
                }
            }
        }
    }
}

fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        title = "海豚投屏",
        state = WindowState(width = 400.dp, height = 800.dp, position = WindowPosition.Aligned(Alignment.Center))
    ) {
        App()
    }

}

fun startScreenCapture(outputFilePath: String): Thread {
    val running = AtomicBoolean(true)

    return Thread {
        try {
            val screenSize = Toolkit.getDefaultToolkit().screenSize
            val robot = Robot()
            val frameRate = 30.0

            // 初始化FFmpeg录制器
            val recorder = FFmpegFrameRecorder (
                outputFilePath,
                screenSize.width,
                screenSize.height
            ).also {
                it.format = "mp4"
                it.videoCodec = avcodec.AV_CODEC_ID_H264
                it.pixelFormat = avutil.AV_PIX_FMT_YUV420P
                it.frameRate = frameRate
                it.videoQuality = 18.0 // 0-51，值越小质量越好
                it.videoBitrate = 4000000
                it.setOption("color_range", "pc")
                it.setOption("colorspace", "bt709")
                it.setOption("color_primaries", "bt709")
                it.setOption("color_trc", "bt709")
                it.setOption("preset", "fast")
                it.start()
            }

            // 创建Java2DFrameConverter用于转换BufferedImage到Frame
            val converter = Java2DFrameConverter()

            // 捕获循环
            while (running.get() && !Thread.currentThread().isInterrupted) {
                val startTime = System.nanoTime()

                // 捕获屏幕
                val capturedImage = robot.createScreenCapture(
                    Rectangle(0, 0, screenSize.width, screenSize.height)
                )

                // 转换为RGB格式的BufferedImage
                val bufferedImage = BufferedImage(
                    capturedImage.width,
                    capturedImage.height,
                    BufferedImage.TYPE_3BYTE_BGR
                ).apply {
                    createGraphics().apply {
                        drawImage(capturedImage, 0, 0, null)
                        dispose()
                    }
                }

                // 转换为JavaCV Frame
                val frame = converter.getFrame(bufferedImage)

                // 记录帧
                recorder.record(frame)

                // 保持帧率稳定
                val elapsed = System.nanoTime() - startTime
                val targetTime = (1_000_000_000 / frameRate).toLong()
                if (elapsed < targetTime) {
                    Thread.sleep((targetTime - elapsed) / 1_000_000)
                }
            }

            recorder.stop()
            recorder.release()
        } catch (e: Exception) {
            // 处理中断异常
            println("录制线程被中断")
            e.printStackTrace()
        }
    }.apply {
        start()
    }
}
